package com.dingreading.cloud.admin.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.admin.dto.*;
import com.dingreading.cloud.admin.entity.*;
import com.dingreading.cloud.admin.service.*;
import com.dingreading.cloud.admin.util.bean.GoodsV3Util;
import com.dingreading.cloud.admin.util.bean.OrderFormV3Util;
import com.dingreading.cloud.common.base.R;
import com.dingreading.cloud.common.util.*;
import com.mybatisflex.core.paginate.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/system/goodsGives/v3")
@Api(tags = "总部-赠品管理v2")
public class GoodsGivesControllerV3 {

    @Resource
    protected GoodsGivesService goodsGivesService;
    @Resource
    protected GoodsTypeService goodsTypeService;
    @Resource
    protected GoodsService goodsService;
    @Resource
    protected CouponsService couponsService;
    @Resource
    protected WhPurchaseGoodsService purchaseGoodsService;
    @Resource
    protected ShopCartService shopCartService;
    @Resource
    protected WhStockInService stockInService;
    @Resource
    protected GoodsTypeComboService goodsTypeComboService;


    @ApiOperation(value = "商品赠品分页列表")
    @PostMapping(value = "/goodsPageList", produces = "application/json; charset=UTF-8")
    public R<Object> goodsPageList(
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品名称") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "状态 1.启用 0.禁用") @RequestParam(value = "enabled", required = false) Integer enabled,
            @ApiParam(value = "查看商品是否加入门店的赠品购物车") @RequestParam(value = "storeUid", required = false) String storeUid,
            @ApiParam(value = "员工uid") @RequestParam(value = "staffUid", required = false) String staffUid
    ) {
        PageDto<GoodsGivesDto> page = goodsGivesService.goodsPageList(pageUtil, keyword, enabled);

        List<GoodsGivesDto> list = page.getList();
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> addGoodsTypeIds = null;
            if (StringUtils.isNotBlank(storeUid)) {
                List<ShopCart> shopCartList = shopCartService.giftMainListByStoreUidAndStaffUid(storeUid, staffUid);
                if (CollectionUtils.isNotEmpty(shopCartList)) {
                    addGoodsTypeIds = shopCartList.stream().map(ShopCart::getGoodsTypeId).collect(Collectors.toList());
                }
            }

            Set<Long> typeIds = new HashSet<>();
            Set<Long> comboTypeIds = new HashSet<>();
            for (GoodsGivesDto dto : list) {
                if (dto.getComboType().equals(0))
                    typeIds.add(dto.getProductId());
                else
                    comboTypeIds.add(dto.getProductId());
            }

            // 查询组合商品的子商品信息
            Map<Long, List<GoodsTypeComboDto>> comboMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(comboTypeIds)) {
                List<GoodsTypeComboDto> goodsTypeComboList = goodsTypeComboService.dtoListByMainGoodsTypeIds(new ArrayList<>(comboTypeIds));
                if (CollectionUtils.isNotEmpty(goodsTypeComboList)) {
                    comboMap = goodsTypeComboList.stream().collect(Collectors.groupingBy(GoodsTypeComboDto::getMainGoodsTypeId));

                    List<Long> childGoodsTypeIds = goodsTypeComboList.stream().map(GoodsTypeComboDto::getGoodsTypeId).collect(Collectors.toList());
                    typeIds.addAll(childGoodsTypeIds);
                }
            }

            List<Long> goodsTypeIds = new ArrayList<>(typeIds);
            // 最近一次采购价
            Map<Long, Double> purchasePriceMap = purchaseGoodsService.getLastByGoodsTypeIds(goodsTypeIds);
            // 商品规格的库存数量
            Map<Long, Integer> stockNumMap = stockInService.getStockNumMap(goodsTypeIds);
            // 商品规格的待发货数量
            Map<Long, Integer> waitSendNumMap = shopCartService.getWaitSendNum(goodsTypeIds);

            for (GoodsGivesDto dto : list) {
                // 最近一次采购价
                Long typeId = dto.getProductId();
                dto.setPurchasePrice(NepUtil.nullToZero(purchasePriceMap.get(typeId)));

                // 是否已加入赠品购物车
                if (addGoodsTypeIds != null)
                    dto.setAddStatus(addGoodsTypeIds.contains(typeId) ? 1 : 0);
                else
                    dto.setAddStatus(0);

                // 库存数量
                if (dto.getComboType().equals(0)) {
                    // 正常商品
                    int stockNum = OrderFormV3Util.getGoodsTypeNum(stockNumMap.get(typeId), waitSendNumMap.get(typeId));
                    dto.setStockNum(stockNum);
                } else {
                    // 组合商品
                    List<GoodsTypeComboDto> comboDtoList = comboMap.get(typeId);
                    // 获取组合商品的最低可售数量和总重量
                    ComboGoodsTypeDto comboGoodsTypeDto = GoodsV3Util.getComboGoodsTypeDto(comboDtoList, stockNumMap, waitSendNumMap);
                    dto.setStockNum(comboGoodsTypeDto.getSaleNum());
                }
            }
        }

        return R.ok(page);
    }


    @ApiOperation(value = "代金券赠品分页列表")
    @PostMapping(value = "/couponPageList", produces = "application/json; charset=UTF-8")
    public R<Object> couponPageList(
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品名称") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "状态 1.启用 0.禁用") @RequestParam(value = "enabled", required = false) Integer enabled
    ) {
        PageDto<JSONObject> page = goodsGivesService.couponPageList(pageUtil, keyword, enabled);
        return R.ok(page);
    }


    @ApiOperation(value = "根据ID获取信息")
    @PostMapping(value = "/getBean", produces = "application/json; charset=UTF-8")
    public R<Object> getBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品id") @RequestParam Long id
    ) {
        GoodsGives data = this.goodsGivesService.getById(id);
        return R.ok(data);
    }

    @Transactional(rollbackFor = DescribeException.class)
    @ApiOperation(value = "添加赠品")
    @PostMapping(value = "/newBean", produces = "application/json; charset=UTF-8")
    public R<Object> newBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品类型 1.代金券 2.商城商品") @RequestParam(value = "type") Integer type,
            @ApiParam(value = "关联的商品id") @RequestParam(value = "productId") Long productId
    ) {
        GoodsGives data = new GoodsGives();
        if (type.equals(1)) {
            boolean b = goodsGivesService.haveByProductId(1, productId);
            if (b) return R.fail("已被添加为赠品，不能重复添加");

            Coupons coupons = couponsService.getById(productId);
            if (Objects.isNull(coupons)) return R.fail("代金券获取失败");
            if (!coupons.getEnabled().equals(1)) return R.fail("代金券已禁用");

        } else {
            boolean b = goodsGivesService.haveByProductId(2, productId);
            if (b) return R.fail("已被添加为赠品，不能重复添加");

            GoodsType goodsType = goodsTypeService.getById(productId);
            if (Objects.isNull(goodsType)) return R.fail("商品规格获取失败");

            Goods goods = goodsService.getById(goodsType.getGoodsId());
            if (Objects.isNull(goods)) return R.fail("商品获取失败");
            if (!goods.getEnabled().equals(1)) return R.fail("商品已下架");

            data.setGoodsId(goods.getId());
        }

        data.setType(type);
        data.setProductId(productId);
        data.setEnabled(1);
        data.setAddStaffUid(headStaffUid);
        data.setAddStaffName(headStaffName);
        data.setLastStaffUid(headStaffUid);
        data.setLastStaffName(headStaffName);
        goodsGivesService.saveOrUpdate(data);
        return R.ok();
    }


    @ApiOperation(value = "删除赠品")
    @DeleteMapping(value = "/dropBean", produces = "application/json; charset=UTF-8")
    public R<Object> dropBean(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品id") @RequestParam(value = "id") Long id
    ) {
        GoodsGives data = goodsGivesService.getById(id);
        if (null == data) return R.fail("赠品获取失败");

//        boolean b = contractGivesService.haveGoodsGiveId(id);
//        if (b)
//            return R.fail("在合同中被赠送，不能删除");

        if (data.getType().equals(2)) {
            boolean b = shopCartService.getByTypeAndGoodsTypeId(3, data.getProductId());
            if (b)
                return R.fail("在商城赠品订单中使用，不能删除");
        }
        int l = goodsGivesService.dropBean(id);
        if (l <= 0) return R.fail("删除失败");
        return R.ok();
    }


    @ApiOperation(value = "更新赠品状态")
    @PostMapping(value = "/updateEnabled", produces = "application/json; charset=UTF-8")
    public R<Object> updateEnabled(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "赠品id") @RequestParam(value = "id") Long id,
            @ApiParam(value = "状态 1.启用 0.禁用") @RequestParam(value = "enabled") Integer enabled
    ) {
        boolean l = goodsGivesService.updateEnabled(id, headStaffUid, headStaffName, enabled);
        if (!l) return R.fail("更新失败");
        return R.ok();
    }


    @ApiOperation(value = "选择商品分页列表")
    @PostMapping(value = "/goodsList", produces = "application/json; charset=UTF-8")
    public R<Object> goodsList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "商品名/商品规格名") @RequestParam(value = "name", required = false) String name,
            @ApiParam(value = "商品种类id") @RequestParam(value = "categoryId", required = false) Long categoryId
    ) {
        PageDto<GoodsAndTypeDto> page = goodsTypeService.goodsTypePageList(pageUtil, name, null, null);

        List<GoodsAndTypeDto> list = page.getList();
        if (CollectionUtils.isNotEmpty(list)) {
            Set<Long> typeIds = new HashSet<>();
            Set<Long> comboTypeIds = new HashSet<>();
            for (GoodsAndTypeDto dto : list) {
                if (dto.getComboType().equals(0))
                    typeIds.add(dto.getGoodsTypeId());
                else
                    comboTypeIds.add(dto.getGoodsTypeId());
            }

            // 查询组合商品的子商品信息
            Map<Long, List<GoodsTypeComboDto>> comboMap = new HashMap<>();
            if (CollectionUtils.isNotEmpty(comboTypeIds)) {
                List<GoodsTypeComboDto> goodsTypeComboList = goodsTypeComboService.dtoListByMainGoodsTypeIds(new ArrayList<>(comboTypeIds));
                if (CollectionUtils.isNotEmpty(goodsTypeComboList)) {
                    comboMap = goodsTypeComboList.stream().collect(Collectors.groupingBy(GoodsTypeComboDto::getMainGoodsTypeId));

                    List<Long> childGoodsTypeIds = goodsTypeComboList.stream().map(GoodsTypeComboDto::getGoodsTypeId).collect(Collectors.toList());
                    typeIds.addAll(childGoodsTypeIds);
                }
            }

            List<Long> goodsTypeIds = new ArrayList<>(typeIds);
            // 最近一次采购价
            Map<Long, Double> unitPriceMap = purchaseGoodsService.getLastByGoodsTypeIds(goodsTypeIds);
            // 商品规格的库存数量
            Map<Long, Integer> stockNumMap = stockInService.getStockNumMap(goodsTypeIds);
            // 商品规格的待发货数量
            Map<Long, Integer> waitSendNumMap = shopCartService.getWaitSendNum(goodsTypeIds);

            // 赠品列表
            goodsTypeIds.addAll(comboTypeIds);
            List<GoodsGives> goodsGivesList = goodsGivesService.getByProductIdsAndType(goodsTypeIds, 2);
            Map<Long, Long> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(goodsGivesList)) {
                map = goodsGivesList.stream().collect(Collectors.toMap(GoodsGives::getProductId, GoodsGives::getId));
            }

            for (GoodsAndTypeDto dto : list) {
                Long goodsTypeId = dto.getGoodsTypeId();
                long giveIds = NepUtil.nullToZero(map.get(goodsTypeId));
                // 是否是赠品
                if (giveIds > 0)
                    dto.setStatus(1);
                else
                    dto.setStatus(0);

                // 最近一次采购价
                dto.setPurchasePrice(NepUtil.nullToZero(unitPriceMap.get(goodsTypeId)));

                // 库存数量
                if (dto.getComboType().equals(0)) {
                    // 正常商品
                    int stockNum = OrderFormV3Util.getGoodsTypeNum(stockNumMap.get(goodsTypeId), waitSendNumMap.get(goodsTypeId));
                    dto.setStockNum(stockNum);
                } else {
                    // 组合商品
                    List<GoodsTypeComboDto> comboDtoList = comboMap.get(goodsTypeId);
                    // 获取组合商品的最低可售数量和总重量
                    ComboGoodsTypeDto comboGoodsTypeDto = GoodsV3Util.getComboGoodsTypeDto(comboDtoList, stockNumMap, waitSendNumMap);
                    dto.setStockNum(comboGoodsTypeDto.getSaleNum());
                    dto.setWeight(comboGoodsTypeDto.getWeight());
                }

            }
        }

        return R.ok(page);
    }


    @ApiOperation(value = "选择代金券分页列表")
    @PostMapping(value = "/couponList")
    public R<Object> couponList(
            @ApiParam(value = "总部员工uid") @RequestParam(value = "headStaffUid") String headStaffUid,
            @ApiParam(value = "总部员工名") @RequestParam(value = "headStaffName") String headStaffName,
            @ApiParam(value = "分页公共类") PageUtil pageUtil,
            @ApiParam(value = "代金券名") @RequestParam(value = "keyword", required = false) String keyword,
            @ApiParam(value = "分类id") @RequestParam(value = "typeId", required = false) Long typeId
    ) {
        Page<CouponsDto> page = this.couponsService.pageList(pageUtil, typeId, keyword, 1);

        List<CouponsDto> list = page.getRecords();
        List<JSONObject> jsonObjects = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(list)) {
            List<Long> ids = list.stream().map(CouponsDto::getId).collect(Collectors.toList());

            List<GoodsGives> goodsGivesList = goodsGivesService.getByProductIdsAndType(ids, 1);
            Map<Long, GoodsGives> map = new HashMap<>();
            if (CollectionUtils.isNotEmpty(goodsGivesList)) {
                map = goodsGivesList.stream().collect(Collectors.toMap(GoodsGives::getProductId, Function.identity()));
            }
            for (CouponsDto coupons : list) {
                JSONObject jsonObject = JsonUtil.toJsonObject(coupons);
                GoodsGives goodsGives = map.get(coupons.getId());
                // 是否是赠品
                if (null != goodsGives)
                    jsonObject.put("giftStatus", 1);
                else
                    jsonObject.put("giftStatus", 0);
                jsonObjects.add(jsonObject);
            }
        }

        PageBeanDto data = new PageBeanDto();
        data.setTotal(page.getTotalRow());
        data.setList(jsonObjects);
        return R.ok(data);
    }

}
